package problems;

import java.math.BigInteger;

import lib.Fraction;

import com.google.common.base.Function;

public class Euler065 extends AbstractEuler {

	@Override
	public Number calculate() {

		EPattern tailPattern = new EPattern();

		Fraction one = new Fraction(1);

		int convergent = 100;
		Fraction tail = new Fraction(tailPattern.get(convergent));
		for (int i = convergent - 1; i >= 1; i--) {
			tail = new Fraction(tailPattern.get(i)).plus(one.dividedBy(tail));
		}

		return lib.MathLib.sumOfDigitsRaisedToPower(tail.getNumerator(), 1);
	}

	@Override
	protected Number getCorrectAnswer() {
		return BigInteger.valueOf(272);
	}

	private class EPattern {

		public EPattern() {
			this(new Function<Integer, Long>() {
				public Long apply(Integer input) {
					if (input < 1) {
						throw new ArrayIndexOutOfBoundsException(input);
					} else if (input == 1) {
						return 2L;
					} else if (input % 3 == 0) {
						return (2L * (input / 3));
					} else {
						return 1L;
					}
				}
			});
		}
		
		final Function<Integer, Long> function;

		public Long get(int i) {
			return this.function.apply(i);
		}
		
		public EPattern(Function<Integer, Long> function) {
			this.function = function;
		}

	}

}
